import package3.Position;
import package3.BackTrack;
import java.io.*;
import java.util.*;

public class KnightUser
{
    public static void main (String[ ] args)
    {
        new KnightUser().run();
    } // method main
    
    public void run()
    {                    
        final String INPUT_PROMPT_BOARD_SIZE =
            "\n\nPlease enter the size of the board (ROWS COLUMNS): ";

        final String INPUT_PROMPT_START_POS =
            "\nPlease enter the starting position (X_Position Y_Position: ";

        final String START_INVALID = "The start position is invalid.";

        final String FINISH_INVALID = "The finish position is invalid.";

        final String FINAL_STATE =
            "The final state is as follows:\n";

        final String SUCCESS = "\n\nA solution has been found:";
        
        final String FAILURE = "\n\nThere is no solution:";

        Knight knight = null;
        
        Scanner keyboardScanner = new Scanner (System.in);
        
        System.out.print (INPUT_PROMPT_BOARD_SIZE);
            byte rows = (byte)keyboardScanner.nextInt();
            byte columns = (byte)keyboardScanner.nextInt();
        System.out.print (INPUT_PROMPT_START_POS);
            int startX = keyboardScanner.nextInt();
            int startY = keyboardScanner.nextInt();
        
        try
        {            
            knight = new Knight (rows, columns, new Position (startX, startY) );
         // System.out.println (knight);  //Do not print out the 'initial' board. It is unnecesary.          
            if (!knight.isOK (knight.getStart()))
                System.out.println (START_INVALID);
            else
            {
                if (searchTour (knight))                
                    System.out.println (SUCCESS);
                else
                    System.out.println (FAILURE);                    
                System.out.println (FINAL_STATE + knight);                                
            } // else valid search
        } // try
        catch (NumberFormatException e)
        {
            System.out.println ("\n" + e);
        } // catch NumberFormatException
        catch (RuntimeException e)
        {
            System.out.println ("\n" + e);
            System.out.println (FINAL_STATE + knight);
        } // catch NumberFormatException
    } // method run


    /**
     * Performs the maze search.
     * 
     * @param maze the maze to be searched.   
     * 
     * @return true - if a path from start to finish was found; otherwise, false
     */
    public boolean searchTour (Knight tour)
    {        
        Position start = tour.getStart();
        tour.markAsPossible (start);
        BackTrack backTrack = new BackTrack (tour);
        if (tour.isGoal (start) || backTrack.tryToReachGoal (start))
            return true;
        tour.markAsDeadEnd (start);
        return false;        
    } // method searchTour

} // class MazeUser
